package com.me.collector;

import java.util.ArrayList;

import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.ChainShape;
import com.badlogic.gdx.physics.box2d.Fixture;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.Shape;
import com.badlogic.gdx.physics.box2d.World;
import com.me.collector.Definitions.EntityCategory;

public class Ground extends StaticObject {
	
	static public final int NumberOfPolygons = 6;
	static public final int Raise = 10;
	static public final float maxDifference = 30;
	
	private ArrayList<Vector2> topPolygons = new ArrayList<Vector2>();
	private Fixture fixture;
	private World world; // For recreating body
	private Physics physics;
	private boolean resetBody = false;
	
	public Ground(World world, Physics physics, int height)
	{
		category = (short)EntityCategory.Ground.getValue();
		this.world = world;
		this.physics = physics;
		for(int x = 0; x <= NumberOfPolygons; x++)
		{
			topPolygons.add(new Vector2(x * Definitions.SCREEN_WIDTH / NumberOfPolygons * Definitions.WORLD_TO_BOX, height * Definitions.WORLD_TO_BOX));
		}
		createBody();
	}
	
	public void raiseGround(Vector2 position)
	{
		Vector2 boxPosition = position.mul(Definitions.WORLD_TO_BOX);
		// Find closest Vector
		int j = 0;
		for(int i = 1; i < topPolygons.size(); i++)
			if(topPolygons.get(i).dst(boxPosition)< topPolygons.get(j).dst(boxPosition))
				j = i;
		// Raise it
		topPolygons.get(j).y += Raise * Definitions.WORLD_TO_BOX;
		// Raise neighboors
		if(j > 0)
			topPolygons.get(j - 1).y += Raise * Definitions.WORLD_TO_BOX / 2f;
		if(j < topPolygons.size() - 1)
			topPolygons.get(j + 1).y += Raise * Definitions.WORLD_TO_BOX / 2f;
		// If necessary lift the polygons that are too low
		float highest = 0;
		for(Vector2 v:topPolygons)
			if(v.y > highest)
				highest = v.y;
		for(Vector2 v:topPolygons)
			if((highest - v.y) * Definitions.BOX_TO_WORLD > maxDifference)
				v.y = highest - maxDifference * Definitions.WORLD_TO_BOX;
		// Recreate Body
		resetBody = true;
	}
	
	public void update()
	{
		if(resetBody)
		{
			resetBody = false;
			world.destroyBody(body);
			createBody();
		}
	}
	
	private void createBody()
	{
		// Create Shape
		ChainShape shape = new ChainShape();
		shape.createChain(topPolygons.toArray(new Vector2[topPolygons.size()]));
		// Create Body
		BodyDef bodyDef = new BodyDef();
		bodyDef.position.set(new Vector2(0, 0));
		body = world.createBody(bodyDef);
		FixtureDef f = new FixtureDef();
		f.shape = shape;
		f.density = physics.getDensity();
		f.friction = physics.getFriction();
		f.restitution = physics.getRestitution();
		f.filter.categoryBits = category;
		f.filter.maskBits = mask;
		fixture = body.createFixture(f);
		shape.dispose();
	}
	
	// properties
	
	public boolean getResetBody()
	{
		return resetBody;
	}
}
